package com.pointi.simGatewayM;

import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.concurrent.ConcurrentLinkedQueue;

public class ThreadSender extends Thread
{
	//____________________________________________________________________________________________________
	// DEF
	
	private ConcurrentLinkedQueue<ThreadSender> activeThreads ;
	private ConfigurationData conf_data ;
	private String filePath ;
	private String fileListPath ;
	private String fileName ;
	private String fileListName ;
	
	//____________________________________________________________________________________________________
	// INIT

	public ThreadSender(ConcurrentLinkedQueue<ThreadSender> inThread)
	{
		activeThreads = inThread ;
	}

	public void start(ConfigurationData conf_data, String fileListPath, String filePath, String fileListName, String fileName)
	{
		this.conf_data = conf_data ;
		this.fileListPath = fileListPath ;
		this.fileListName = fileListName ;
		this.filePath = filePath ;
		this.fileName = fileName ;
		activeThreads.add(this) ;
		super.start();
	}

	//____________________________________________________________________________________________________
	// RUN // Gateway Sender //

	public void run()
	{
		Socket socket = null ;
		try {
			/** Open Socket **/
			String ServerIP = conf_data.s_gateway_address ;
			int ServerPort = Integer.valueOf(conf_data.s_gateway_port) ;
			try {
				socket = new Socket(ServerIP, ServerPort) ;
				System.out.println("[SM] Connection Accept : " + socket.getInetAddress() + ":" + socket.getPort()) ;
			} catch (Exception e) { e.printStackTrace() ; }
			
			DataInputStream dis = new DataInputStream(socket.getInputStream()) ;
			DataOutputStream dos = new DataOutputStream(socket.getOutputStream()) ;
			/** Send **/
			this.fnSendFileList(socket, dos) ; // 001
			if (dis.readBoolean()) {
				this.fnSendFile(socket, dos) ; // 002
			} else {
				System.out.println(String.format("[SM] FileList Send Error : ", this.fileListName)) ;
			}
			if (!dis.readBoolean()) {
				System.out.println(String.format("[SM] File Send Error : ", this.fileName)) ;
			}
			/** Close Socket **/
			dos.close() ;
			socket.close() ; 	
		}
		catch (Exception e) { e.printStackTrace() ; }
		finally { try { socket.close() ; } catch(Exception e) { e.printStackTrace() ; } }
		activeThreads.remove(this) ;
	}
	
	//____________________________________________________________________________________________________
	// 001 // SEND FILELIST
	
	private void fnSendFileList(Socket socket, DataOutputStream dos)
	{
		File mFile = new File(fileListPath) ;
		int fileLength = (int)mFile.length() ;
		try {
			dos.writeUTF(fileListName) ;
			dos.flush() ;
			dos.writeUTF(String.valueOf(mFile.length())) ;
			dos.flush() ;
		} catch (IOException e) { e.printStackTrace() ; }
		try {
			int mFrameLength = 100 ;
			int SP = 0 ;
			int EP = fileLength ;
			byte [] mContainer = new byte [mFrameLength] ;
			FileInputStream fio = new FileInputStream(mFile) ;
			BufferedInputStream bis = new BufferedInputStream(fio) ;
			while(SP < EP) {
				if ((SP+mFrameLength) > EP) mFrameLength = EP - SP ;
				bis.read(mContainer, 0, mFrameLength) ;
				dos.write(mContainer, 0, mFrameLength) ;
				dos.flush() ;
				SP += mFrameLength ;
			}
			bis.close() ;
		} catch (IOException e) { e.printStackTrace() ; }		
	}
	
	//____________________________________________________________________________________________________
	// 002 // SEND FILE
	
	private void fnSendFile(Socket socket, DataOutputStream dos)
	{
		File mFile = new File(filePath) ;
		int fileLength = (int)mFile.length() ;
		try {
			dos = new DataOutputStream(socket.getOutputStream()) ;
			dos.writeUTF(fileName) ;
			dos.flush() ;
			dos.writeUTF(String.valueOf(mFile.length())) ;
			dos.flush() ;
			System.out.println("[SM][CRT] File Send : " + fileName + " (" + String.valueOf(mFile.length()) + " bytes) ") ;
		} catch (IOException e) { e.printStackTrace() ; }
		try {
			int mFrameLength = 100 ;
			int SP = 0 ;
			int EP = fileLength ;
			byte [] mContainer = new byte [mFrameLength] ;
			FileInputStream fio = new FileInputStream(mFile) ;
			BufferedInputStream bis = new BufferedInputStream(fio) ;
			while(SP < EP) {
				if ((SP+mFrameLength) > EP) mFrameLength = EP - SP ;
				bis.read(mContainer, 0, mFrameLength) ;
				dos.write(mContainer, 0, mFrameLength) ;
				dos.flush() ;
				SP += mFrameLength ;
			}
			bis.close() ;
		} catch (IOException e) { e.printStackTrace() ; }
	}

	//____________________________________________________________________________________________________
	// EOC
}
